package com.wys.utils.password;

import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.KeyUtil;
import cn.hutool.crypto.asymmetric.AsymmetricAlgorithm;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import com.wys.api.exception.BizException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.KeyPair;
import java.security.interfaces.RSAPrivateKey;
import java.util.HashMap;
import java.util.Map;

public class RSAUtils {

    private static final Logger logger = LoggerFactory.getLogger(RSAUtils.class);

    public static RSA rsa;

    private static final String DEFAULT_PRIVATE_KEY = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAL3BpS093xr4oWq/wKeXO9CT6Bzcs+D0c5vZUs0FSa88KxvwCK+YVITgfZOBVbrASa9RP4XRjR3ONrOAK5d69bYw7HZ0BQPUHK3/keQCDnXihNFxtoW6GHg6sz6hMXfkAdBbuUu+yDgX0MvJRSo0JBgf8MOiRKvK/1m2VVt6nBXtAgMBAAECgYBq+sV44CzsM8gtOrYOxgB+8yQlQXhYFvkmoDtCQvzrwmw7b/Q1qxfbYgTqKDyA8O+Z26CIfT+l0iCcymHJIRVtDPQXPSI9PD5tD6FlyVBJ2QnPrGCDYh79dmmSmNJRqZixZioH18pr2b5LqmkrYeDkhEHNNKGbDwY60OPKsgOJMQJBAOlQZf/IBaVdP9PmkLUQUJtfUJkW2cSMXkfX5ZBXTJHLwNFHbOJBxknQ42P8ZeFLIuzD1cFGv5hbHFAJJfwEuG8CQQDQNQUcO+xfY6h+4RT6v8QLuowxq2WLt2T9emxBZuMKvx3SXkMs/iWBU3w/jxEEPzVLvghpohsyjKtuybs7lu1jAkEAv+AP0lgkVIeou1LNxSqCsBSmCxCgzSSHUNw7/gXdgbWogDQWVsizEvfIWe0zuCF7um2fuFC/tsOPOD8dzvHu3wJBAKxfCMEMNy/twMRyMb06X+LZ6VEBtgsKpNhZryAiPttZyCWulmy8Z25/IIE6P3tFnSj8xdg2NdAOt6r75j96P0MCQG9RbC9TVUKArQxggnF+a3t1UxrOC7JitbcMhRfsX9lSDSL/FV3TyAKDauawBvLZHDufJOME3NGkMsKOUE22/jA=";

    private static final String DEFAULT_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9waUtPd8a+KFqv8CnlzvQk+gc3LPg9HOb2VLNBUmvPCsb8AivmFSE4H2TgVW6wEmvUT+F0Y0dzjazgCuXevW2MOx2dAUD1Byt/5HkAg514oTRcbaFuhh4OrM+oTF35AHQW7lLvsg4F9DLyUUqNCQYH/DDokSryv9ZtlVbepwV7QIDAQAB";


    static {
        rsa = new RSA(AsymmetricAlgorithm.RSA_ECB_PKCS1.getValue(), DEFAULT_PRIVATE_KEY, DEFAULT_PUBLIC_KEY);
    }


    public RSAUtils(String privateKey, String publicKey) {
        rsa = new RSA(AsymmetricAlgorithm.RSA_ECB_PKCS1.getValue(), privateKey, publicKey);
    }

    /**
     * 加密
     * @param content
     * @return
     */
    public static String encryptHex(String content) {
        try {
            return RSAUtils.rsa.encryptHex(content, KeyType.PublicKey);
        } catch (Exception e) {
            logger.error("RSA加密异常:",e);
            throw new BizException("RSA加密异常");
        }
    }


    /**
     * 解密
     * @param pwdContent
     * @return
     */
    public static String decryptStr(String pwdContent) {
        try {
            return RSAUtils.rsa.decryptStr(pwdContent, KeyType.PrivateKey);
        } catch (Exception e) {
            logger.error("RSA解密异常:",e);
            throw new BizException("RSA解密异常");
        }
    }

    /**
     * size 值越小加解密操作越快 经测试 size为2048加密为23ms左右 解密为31ms左右
     * size为5120 解密为128ms左右
     *
     * @param size
     * @return
     */
    public static Map<String, String> KeyGenerator(int size) {
        Map<String, String> map = new HashMap<>();
        KeyPair keyPair = KeyUtil.generateKeyPair(AsymmetricAlgorithm.RSA_ECB_PKCS1.getValue(), size);
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
        map.put("private", Base64.encode(rsaPrivateKey.getEncoded()));
        map.put("public", Base64.encode(keyPair.getPublic().getEncoded()));
        if (logger.isDebugEnabled()) {
            logger.debug("=========privateKey:{}==============public:{}========", map.get("private"), map.get("public"));
        }
        return map;
    }

    public static void main(String[] args) {

        long start = System.currentTimeMillis();
        String content = "{\"userId\":\"11\",\"script\":{\"input\":\"喜欢你迷人的眼睛,思考的表情,动听的声音~~~\",\"provider\":{\"type\":\"microsoft\",\"voice_id\":\"zh-CN-XiaoxiaoNeural\"},\"type\":\"text\"},\"source_url\":\"https://fyfile.dg.cn///168109270700120230410101123.png\"}";
        System.out.println("加密字符长度：" + content.length());
        String pwd = RSAUtils.rsa.encryptHex(content, KeyType.PublicKey);

        System.out.println("加密后的数据：" + pwd + "=========加密耗时：" + (System.currentTimeMillis() - start) + "ms");
        System.out.println("RSA解密后的数据:" + RSAUtils.rsa.decryptStr("89edf30ca8593326c8301c130c3b73a73712832dd727102b37e92f93a4f3feca831328ab1380ac68bff8c13833e2e7d8dc07dcb8f74e63e3cbd6c039b8fddd2382b23fbc8eaa750f637ea238ca768fc2f8b67bba57aa0c4069807a433b5ca5bab593025ac2475073a17c7b2ea25273ce39ccaca4abd6b263bb9c49730840fb68", KeyType.PrivateKey) + "=========解密耗时：" + (System.currentTimeMillis() - start) + "ms");
        System.out.println("=========总耗时：" + (System.currentTimeMillis() - start) + "ms");
    }


}
